#pragma once
#ifndef __USER_QUERY__INCLUDED__HH__
#define __USER_QUERY__INCLUDED__HH__

#include <LitPrerequisites.h>
#include "UserDrag.h"
#include <OgreRay.h>
#include <OgreSceneQuery.h>
#include <OgrePlaneBoundedVolume.h>

#include <qwidget.h>

enum UserQueryFlag
{
	UQF_NONE = 0xFFFFFF,
	UQF_SELECTABLE = 1<<1
};

typedef Lit::Flags<UserQueryFlag> UserQueryFlags;

namespace Lit
{
	class SceneManager;
};
class UserSceneQuery : public QWidget
{
public:
	static const short MIN_VOLUME_SIZE = 10;
	
	struct Result
	{
		struct HitPoint
		{
			HitPoint();
			HitPoint(Lit::Vec3 point_,Ogre::MovableObject* obj);
			HitPoint(const HitPoint& rk);
			~HitPoint();

			HitPoint& operator=(const HitPoint& rk);
			Lit::Vec3 point;
			Ogre::MovableObject* movable;
		};
		Result(const Result& rk);
		Result();
		~Result();
		Result& operator=(const Result& rk);
		
		HitPoint& firstContact();
		const HitPoint& firstContact() const;

		bool					hit;
		bool					volume;
		std::vector<HitPoint>	contacts;
		UserQueryFlags			flags;
	};

protected:
	Ogre::Ray									mRay;
	Ogre::PlaneBoundedVolume					mVolume;

	Ogre::RaySceneQuery*						mRayQuery;
	Ogre::PlaneBoundedVolumeListSceneQuery *	mVolumeQuery;

	Lit::RefPtr<Lit::SceneManager>					mSceneMgr;
	QWidget *									mParent;
	Result										mLastResult;

	void updateRayQuery( Lit::OgreCameraPtr camera, float dx, float dy );
	void updateVolumeQuery( Lit::OgreCameraPtr camera, float dx, float dy, float dx2, float dy2 );

public:
	UserSceneQuery( QWidget * render_parent, Lit::RefPtr<Lit::SceneManager> mgr  ) ;
	~UserSceneQuery();

	const Result& lastResult() const{ return mLastResult; }
	Result& lastResult(){ return mLastResult; }

	Ogre::Ray&										userRay();
	Ogre::RaySceneQuery*							userRayQuery();

	Ogre::PlaneBoundedVolume&						userVolume();
	Ogre::PlaneBoundedVolumeListSceneQuery*			userVolumeQuery();

	const Ogre::Ray&								userRay() const;
	const Ogre::RaySceneQuery*						userRayQuery() const;

	const Ogre::PlaneBoundedVolume&					userVolume() const;
	const Ogre::PlaneBoundedVolumeListSceneQuery*	userVolumeQuery() const;

	void clearResults();
	
	Result execute( Lit::OgreCameraPtr camera, QPoint mouse_local_pos_1, QPoint mouse_local_pos_2 );
	Result execute( Lit::OgreCameraPtr camera, QPoint mouse_local_pos_1 );
	
	//------------------------------/
};

typedef Lit::RefPtr<UserSceneQuery> UserQueryPtr;
typedef UserSceneQuery::Result		UserQueryResult;
#endif